package main

import (
	"fmt"
	"github.com/bxcodec/faker/v3"
	"github.com/panjf2000/ants/v2"
	"os"
	"sync"
	"time"
)

const (
	poolSize2   = 10    // 协程池大小
	fileCount   = 10    // 文件数量
	contentSize = 10000 // 每个文件写入内容大小（字节）
	loopTimes   = 50
)

func generatePhrase(times int) string {
	var sentence string
	for i := 0; i < times; i++ {
		fakeData := struct {
			Name        string
			Address     string
			Email       string
			PhoneNumber string
			DateOfBirth string
			Company     string
			Job         string
			Bio         string
			Sentence    string
		}{}
		// 填充随机数据
		err := faker.FakeData(&fakeData)
		if err != nil {
			panic(err)
			continue
		}
		sentence += fmt.Sprintf("姓名: %s\n地址: %s\n邮箱: %s\n电话: %s\n生日: %s\n公司: %s\n职位: %s\n简介: %s\n摘要: %s \n", fakeData.Name, fakeData.Address, fakeData.Email, fakeData.PhoneNumber, fakeData.DateOfBirth, fakeData.Company, fakeData.Job, fakeData.Bio, fakeData.Sentence)
	}
	return sentence

}
func main() {

	// 初始化协程池
	pool, _ := ants.NewPool(poolSize2)
	defer pool.Release()

	var wg sync.WaitGroup
	errorChan := make(chan error, fileCount) // // 错误收集通道
	// 	// 创建测试文件列表
	files := make([]string, fileCount)
	for i := 0; i < fileCount; i++ {
		filenameTmp := fmt.Sprintf("./txt/data_%d.txt", i) // 生成文件名

		files[i] = filenameTmp
	}

	// 1. 创建/打开文件（不存在则自动创建）
	// os.O_CREATE: 文件不存在时创建
	// os.O_WRONLY: 只写模式
	// os.O_TRUNC: 如果文件存在，清空内容
	// 0644: 文件权限（-rw-r--r--）
	writeTask := func(filename string) {
		defer wg.Done()
		// 创建文件（追加模式，读写权限）
		file, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
		if err != nil {
			errorChan <- fmt.Errorf("create file %s failed : %v ", filename, err)
			return
		}

		defer file.Close()
		// 生成测试内容（优化内存分配）
		content := make([]byte, contentSize)
		for i := 0; i < contentSize; i++ {
			content[i] = byte(i % 256)
		}
		// 分块写入（模拟大数据量写入）
		chunkSize := 4096
		if false {
			for i := 0; i < len(content); i += chunkSize {
				end := i + chunkSize
				if end > len(content) {
					end = len(content)
				}
				if _, err := file.Write(content[i:end]); err != nil {
					errorChan <- fmt.Errorf("write file %s failed : %v ", filename, err)
					return
				}
				// 模拟处理耗时（实际生产环境应删除）
				//time.Sleep(10 * time.Millisecond)

			}
		}
		generateContent := generatePhrase(loopTimes)
		generateContent += "started " + time.Now().String()
		if _, err := file.WriteString(generateContent); err != nil {
			errorChan <- fmt.Errorf("write file %s failed : %v ", filename, err)
		}

		fmt.Printf("文件 %s 写入完成\n", filename)
	}
	// 提交任务到协程池

	start := time.Now()
	for _, file := range files {
		wg.Add(1)
		// 创建局部变量副本
		f := file
		err := pool.Submit(func() {
			writeTask(f)
		})
		if err != nil {
			wg.Done()
			errorChan <- fmt.Errorf("write file failed : %v ", err)
		}
	}

	// 等待所有任务完成
	wg.Wait()
	close(errorChan)

	end := time.Now()
	duration := end.Sub(start)
	fmt.Println("耗时： ", duration)
	for err := range errorChan {
		fmt.Println("错误： ", err)
	}

}
